home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / newsgate / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-10-09  |  54.3 KB

  1. Subject:  v24i053:  News/mail gateway package, Part03/04
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 6342786c 23d62120 ba41572d 33d067e2
  5.  
  6. Submitted-by: Rich $alz <rsalz@bbn.com>
  7. Posting-number: Volume 24, Issue 53
  8. Archive-name: newsgate/part03
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  gate.h hdr.c lex.l mail-interface mail2news.1 misc.c
  17. #   news2mail.1 signoff.c sysexits.h uucp-2-inet
  18. # Wrapped by rsalz@litchi.bbn.com on Fri Mar 15 16:42:27 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. echo If this archive is complete, you will see the following message:
  21. echo '          "shar: End of archive 3 (of 4)."'
  22. if test -f 'gate.h' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'gate.h'\"
  24. else
  25.   echo shar: Extracting \"'gate.h'\" \(6518 characters\)
  26.   sed "s/^X//" >'gate.h' <<'END_OF_FILE'
  27. X/*
  28. X**  HEADER FILE FOR NEWS/MAIL GATEWAY CODE.
  29. X**  $Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/gate.h,v 1.12 91/03/13 15:59:23 rsalz Exp $
  30. X*/
  31. X
  32. X
  33. X/*
  34. X**  START OF CONFIGURATION SECTION
  35. X*/
  36. X
  37. X
  38. X/* Paths to some parts of your netnews installation.  Required. */
  39. X#define INEWS        "/usr/lib/news/inews"
  40. X#define ACTIVE        "/usr/lib/news/active"
  41. X#define NGDELIM        ','
  42. X
  43. X
  44. X/* In writing Paths into From addresses, we can look at the output
  45. X * of uuname from the L.sys file.  Define both or neither of the next
  46. X * two.  We can also map some UUCP names to their domain names, if
  47. X * the third line is enabled.  The UUCP_INET should match the value
  48. X * in the Makefile.  This violates the "write once" rule, but it's
  49. X * too much of a pain to fix for this one symbol. */
  50. X#define UUNAME        "/usr/lib/news/.admin/uuname.out"
  51. X#define L_SYS        "/usr/lib/uucp/L.sys"
  52. X#define UUCP_INET    "/usr/lib/news/.admin/uucp-2-inet"
  53. X
  54. X
  55. X/* Where does the control file for talk.foo live?
  56. X *    IN_ONEPLACE:    specified filename
  57. X *    IN_SPOOLDIR:    /usr/spool/news/talk/foo/recnews.cmd
  58. X *    IN_CMDDIR:    /usr/lib/news/.admin/talk.foo
  59. X * One of these is required, but you can set IN_ONEPLACE to /dev/null to
  60. X * disable the newsgroup editing. */
  61. X/*efine IN_ONEPLACE    "/dev/null"        /* .. */
  62. X/*efine IN_SPOOLDIR    "/usr/spool/news"    /* .. */
  63. X#define    IN_CMDDIR    "/usr/lib/news/.admin"    /* .. */
  64. X
  65. X
  66. X/* What do you want to do with the Path: line?  Put in a fixed string
  67. X * (such as pointing to a mail reflector saying "Don't trust Path:
  68. X * lines as a way to reply").  Put a fixed "fake host" in the Path:,
  69. X * or just put the user's host there.  The latter two can cause the
  70. X * poster's site to never get the article.  Anyhow, pick one.  To pick
  71. X * neither #define is to get the third behavior -- the user's host. */
  72. X#define FIXED_PATH    "news-mail-gateway"    /* .. */
  73. X/*efine    GATEWAY_NAME    "gateway"        /* .. */
  74. X
  75. X
  76. X/* The code in hdr.c does lots of work to canonicalize addresses.  You
  77. X * shouldn't disable it, but at least one beta-tester wanted to, sigh. */
  78. X#define DO_ADDRESS_CLEANUP            /* .. */
  79. X
  80. X
  81. X/* Are you running sendmail or MMDF?  Pick one.  If you believe in
  82. X * trusted users (MMDF doesn't?) to lie to your mailer, set the
  83. X * user-ID. */
  84. X/*efine SENDMAIL    "/usr/lib/sendmail"    /* .. */
  85. X#define    MMDF        "/usr/mmdf/lib/submit"    /* .. */
  86. X/*efine TRUSTED        1            /* .. */
  87. X
  88. X
  89. X/* Does your Sendmail mailer have the M flag on? */
  90. X#ifdef    SENDMAIL
  91. X#define REQUIRE_MESSAGE_ID            /* .. */
  92. X#endif    /* SENDMAIL */
  93. X
  94. X
  95. X/* I love how we all speak the same language. */
  96. X/*efine CATCHER        int        /* Type of a signal-catcher    */
  97. X#define CATCHER        void        /* .. */
  98. X#define IDX        index        /* .. */
  99. X#define RDX        rindex        /* .. */
  100. X/*efine IDX        strchr        /* .. */
  101. X/*efine RDX        strrchr        /* .. */
  102. Xtypedef int        *align_t;    /* Worst-case alignment, for lint */
  103. X#define CHARSTAR_SPRINTF        /* Need extern char *sprintf();    */
  104. X#define VOID_EXIT            /* Need extern void exit();    */
  105. X#define HAVE_SYSEXITS            /* Have <sysexits.h>?        */
  106. X#define HAVE_TIMEB            /* Have <sys/timeb.h>?        */
  107. X#define HAVE_PUTENV            /* Have putenv(3)        */
  108. X/*efine HAVE_STRERROR            /* Have strerror(3)?        */
  109. X
  110. X#define SM_SIZE        512        /* A smallish buffer size    */
  111. X#define LG_SIZE        1024        /* big buffer size        */
  112. X
  113. X/* Error log (stderr) for news2mail. */
  114. X#define ERR_LOG        "/usr/lib/news/.admin/news2mail.out"
  115. X#define TEMPFILE    "/tmp/gateXXXXXX" /* Temporary file pattern    */
  116. X
  117. X
  118. X/* Enable debugging code? */
  119. X#define STATIC        static
  120. X#ifdef    lint
  121. X#undef    RCSID
  122. X#else
  123. X#define RCSID
  124. X#endif    /* lint */
  125. X
  126. X/*
  127. X**  END OF CONFIGURATION SECTION.
  128. X*/
  129. X
  130. X
  131. X
  132. X#include <stdio.h>
  133. X#include <ctype.h>
  134. X#include <sys/types.h>
  135. X
  136. X#ifdef    HAVE_SYSEXITS
  137. X#include <sysexits.h>
  138. X#else
  139. X#include "sysexits.h"
  140. X#endif    /* HAVE_SYSEXITS */
  141. X
  142. X
  143. Xtypedef struct _HBUF {
  144. X    char    approved[SM_SIZE];    /* Approved:        */
  145. X    char    ctlmsg[LG_SIZE];    /* Control:        */
  146. X    char    subdate[SM_SIZE];    /* Date: (submission)    */
  147. X    char    distribution[SM_SIZE];    /* Distribution:    */
  148. X    char    expdate[SM_SIZE];    /* Expires:        */
  149. X    char    followto[SM_SIZE];    /* Followup-to:        */
  150. X    char    from[SM_SIZE];        /* From:        */
  151. X    char    followid[SM_SIZE];    /* References:        */
  152. X    char    keywords[SM_SIZE];    /* Keywords:        */
  153. X    char    ident[SM_SIZE];        /* Message-ID:        */
  154. X    char    nbuf[LG_SIZE];        /* Newsgroups:        */
  155. X    char    organization[SM_SIZE];    /* Organization:    */
  156. X    char    title[SM_SIZE];        /* Subject:        */
  157. X    char    replyto[SM_SIZE];    /* Reply-To:        */
  158. X    char    summary[SM_SIZE];    /* Summary:        */
  159. X    char    path[LG_SIZE];        /* Path:        */
  160. X    char    sender[SM_SIZE];    /* Sender:        */
  161. X} HBUF;
  162. X
  163. X
  164. X/* String and memory manipulators. */
  165. X#define APPEND(p, t)    strlen(strcpy((p), (t)))
  166. X#define NEW(T, c)    (T *)MyAlloc((c) * sizeof (T))
  167. X#define COPY(s)        ((s) ? strcpy(NEW(char, strlen((s)) + 1), (s)) : NULL)
  168. X#define REALLOC(p, s)    realloc((char *)(p), (unsigned int)(s))
  169. X
  170. X
  171. X/* Array sizing. */
  172. X#define SIZEOF(x)    (sizeof x / sizeof x[0])
  173. X#define ENDOF(x)    (&x[SIZEOF(x)])
  174. X
  175. X
  176. X/* String and character operations. */
  177. X#define WHITE(c)    ((c) == ' ' || (c) == '\t')
  178. X#define EQ(a, b)    ((a)[0] == (b)[0] && strcmp((a), (b)) == 0)
  179. X#define EQn(a, b, n)    ((a)[0] == (b)[0] && strncmp((a), (b), (n)) == 0)
  180. X#define NETCHR(c)    ((c) == '.' || (c) == '%' || (c) == '@' || (c) == '!')
  181. X#define CHREQ(c, d)    ((d) == (islower((c)) ? toupper((c)) : (c)))
  182. X
  183. X
  184. X/* Fundamental constants of the universe. */
  185. X#define TRUE        1
  186. X#define FALSE        0
  187. X#define FAIL        (-1)
  188. X
  189. X
  190. X/* SHUT UP! */
  191. X#ifdef    lint
  192. X#undef    putc
  193. X#undef    putchar
  194. X#endif    /* lint */
  195. X
  196. X#define Close        (void)close
  197. X#define Fflush        (void)fflush
  198. X#define Fprintf        (void)fprintf
  199. X#define Fputs        (void)fputs
  200. X#define Signal        (void)signal
  201. X#define Sprintf        (void)sprintf
  202. X#define Strcpy        (void)strcpy
  203. X#define Strcat        (void)strcat
  204. X#define Strncpy        (void)strncpy
  205. X
  206. X
  207. X/*
  208. X**  External declarations.
  209. X*/
  210. X
  211. X/* Program name; exists once for each main(). */
  212. Xextern    char    *Pname;
  213. X
  214. X/* Routines we provide. */
  215. Xextern align_t    MyAlloc();
  216. Xextern int    Split();
  217. Xextern int    CrackFrom();
  218. Xextern void    re_modw();
  219. Xextern void    SplitFree();
  220. Xextern void    FreeFile();
  221. Xextern char    **ReadFile();
  222. Xextern char    *re_comp();
  223. Xextern char    *HackHeader();
  224. X
  225. Xextern char    *strerror();
  226. X
  227. X/* Variables and routines that Unix(tm) provides. */
  228. Xextern int    errno;
  229. Xextern int    sys_nerr;
  230. Xextern int    optind;
  231. Xextern char    *sys_errlist[];
  232. Xextern char    **environ;
  233. Xextern char    *optarg;
  234. X
  235. Xextern FILE    *popen();
  236. Xextern char    *IDX();
  237. Xextern char    *RDX();
  238. Xextern char    *ctime();
  239. Xextern char    *malloc();
  240. Xextern char    *mktemp();
  241. Xextern char    *realloc();
  242. Xextern char    *strcat();
  243. Xextern char    *strncat();
  244. Xextern char    *strcpy();
  245. Xextern char    *strncpy();
  246. X#ifdef    CHARSTAR_SPRINTF
  247. Xextern char    *sprintf();
  248. X#endif    /* CHARSTAR_SPRINTF */
  249. X#ifdef    VOID_EXIT
  250. Xextern void    exit();
  251. X#endif    /* VOID_EXIT */
  252. END_OF_FILE
  253.   if test 6518 -ne `wc -c <'gate.h'`; then
  254.     echo shar: \"'gate.h'\" unpacked with wrong size!
  255.   fi
  256.   # end of 'gate.h'
  257. fi
  258. if test -f 'hdr.c' -a "${1}" != "-c" ; then 
  259.   echo shar: Will not clobber existing file \"'hdr.c'\"
  260. else
  261.   echo shar: Extracting \"'hdr.c'\" \(10652 characters\)
  262.   sed "s/^X//" >'hdr.c' <<'END_OF_FILE'
  263. X/*
  264. X**  Header-cracking and address re-writing routines, with sincere
  265. X**  apologies to Upas and Sendmail.
  266. X*/
  267. X#include "gate.h"
  268. X#include <netdb.h>
  269. X#ifdef    RCSID
  270. Xstatic char RCS[] =
  271. X    "$Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/hdr.c,v 1.15 91/03/15 16:39:42 rsalz Exp $";
  272. X#endif    /* RCSID */
  273. X
  274. X
  275. X#ifdef    TEST
  276. X#ifndef    DO_FIX_ADDRESS
  277. X#define DO_FIX_ADDRESS
  278. X#endif    /* DO_FIX_ADDRESS */
  279. X#define dprintf(string, buff)    (void)printf((string), (buff))
  280. X#else
  281. X#define dprintf(string, buff)    /* NULL */
  282. X#endif    /* TEST */
  283. X
  284. X
  285. X/*
  286. X**  List of domains that we recognize.
  287. X*/
  288. XSTATIC char    RELAY_CS_NET[] = "RELAY.CS.NET";
  289. XSTATIC char    *Domains[] = {
  290. X    /* Don't undo the % hack for sites @RELAY.CS.NET, sigh #1. */
  291. X    RELAY_CS_NET,
  292. X    /* These aren't official domains, but we use them, sigh #2. */
  293. X    ".BITNET",
  294. X    ".UUCP",
  295. X    /* Official organizational domains. */
  296. X    ".ARPA",    ".COM",    ".EDU",    ".GOV",    ".INT",    ".MIL",
  297. X    ".NATO",    ".NET",    ".ORG",
  298. X    /* Official natonal domans. */
  299. X    ".AR",    ".AT",    ".AU",    ".BE",    ".BR",    ".CA",    ".CH",    ".CL",
  300. X    ".CN",    ".CR",    ".CS",    ".DE",    ".DK",    ".EC",    ".EG",    ".ES",
  301. X    ".FI",    ".FR",    ".GR",    ".HK",    ".HU",    ".IE",    ".IL",    ".IN",
  302. X    ".IS",    ".IT",    ".JP",    ".KR",    ".LK",    ".MX",    ".MY",    ".NI",
  303. X    ".NL",    ".NO",    ".NZ",    ".PH",    ".PL",    ".PR",    ".PT",    ".SE",
  304. X    ".SG",    ".SU",    ".TH",    ".TR",    ".TW",    ".UK",    ".US",    ".UY",
  305. X    ".YU",    ".ZA"
  306. X};
  307. X
  308. X
  309. X/*
  310. X**  Local user?
  311. X*/
  312. XSTATIC int
  313. XLocal(p)
  314. X    register char    *p;
  315. X{
  316. X    for ( ; *p; p++)
  317. X    if (NETCHR(*p))
  318. X        break;
  319. X    return *p == '\0';
  320. X}
  321. X
  322. X
  323. X/*
  324. X**  Case-insensitive strncmp.
  325. X*/
  326. XSTATIC char *
  327. XFound(dp, p)
  328. X    register char    *dp;
  329. X    register char    *p;
  330. X{
  331. X    register char    *q;
  332. X    register char    *r;
  333. X
  334. X    for ( ; *p; p++)
  335. X    if (CHREQ(*p, *dp)) {
  336. X        for (q = p, r = dp; *r && CHREQ(*q, *r); q++, r++)
  337. X        ;
  338. X        if (*r == '\0')
  339. X        return p;
  340. X    }
  341. X
  342. X    return NULL;
  343. X}
  344. X
  345. X
  346. X/*
  347. X**  Find all domain names and make them uppercase:
  348. X**    joe%site.edu@relay.cs.net --> joe%site.EDU@RELAY.CS.NET
  349. X*/
  350. XSTATIC void
  351. XCasify(p)
  352. X    register char    *p;
  353. X{
  354. X    register char    *q;
  355. X    register char    *r;
  356. X    register char    **dp;
  357. X
  358. X    for (dp = Domains; dp < ENDOF(Domains); dp++)
  359. X    for (q = p; q = Found(*dp, q); )
  360. X        for (r = *dp; *r; *q++ = *r++)
  361. X        ;
  362. X}
  363. X
  364. X
  365. X/*
  366. X**  Handle route-addresses:
  367. X**    @cruft:joe@site --> joe@site
  368. X*/
  369. XSTATIC void
  370. XRouteAddr(p)
  371. X    register char    *p;
  372. X{
  373. X    register char    *q;
  374. X    register char    *r;
  375. X
  376. X    for (r = p; *p == '@'; p = q)
  377. X    if ((q = IDX(p, ':')) && IDX(q, '@'))
  378. X        *q++ = '\0';
  379. X    else
  380. X        break;
  381. X    if (p > r)
  382. X    /* Avoid overlaping strcpy() call. */
  383. X    while (*r++ = *p++)
  384. X        ;
  385. X}
  386. X
  387. X/*
  388. X**  Does the pattern exist in the character range between p and end?
  389. X*/
  390. XSTATIC int
  391. XBetween(p, pat, q)
  392. X    register char    *p;
  393. X    register char    *pat;
  394. X    register char    *q;
  395. X{
  396. X    register char    *r;
  397. X
  398. X    for (r = pat + strlen(pat); p < q && r >= pat && *--q == *--r; )
  399. X    ;
  400. X    return *r == '\0';
  401. X}
  402. X
  403. X
  404. X/*
  405. X**  Handle the '%' syntax:
  406. X**    joe%site.EDU@gateway.DOMAIN -> joe@site.EDU
  407. X*/
  408. XSTATIC void
  409. XPercent(p)
  410. X    register char    *p;
  411. X{
  412. X    register char    *q;
  413. X    register char    *r;
  414. X    register char    **dp;
  415. X
  416. X    while ((r = IDX(p, '%')) && (q = IDX(r, '@'))) {
  417. X    for (dp = Domains; dp < ENDOF(Domains); dp++) {
  418. X        if (*dp == RELAY_CS_NET)
  419. X        continue;
  420. X        if (Between(r, *dp, q)) {
  421. X        *RDX(p, '@') = '\0';
  422. X        *RDX(p, '%') = '@';
  423. X        break;
  424. X        }
  425. X    }
  426. X    if (dp == ENDOF(Domains))
  427. X        break;
  428. X    }
  429. X}
  430. X
  431. X
  432. X/*
  433. X**  Handle CSNET, which is domainist except in some people's minds:
  434. X**    joe%site@RELAY.CS.NET --> joe@site.CSNET
  435. X**    joe%site.EDU@RELAY.CS.NET --> joe@site.EDU
  436. X*/
  437. XSTATIC void
  438. XCsnet(p)
  439. X    register char    *p;
  440. X{
  441. X    register char    *q;
  442. X    register char    *r;
  443. X
  444. X    if ((q = RDX(p, '@'))
  445. X     && strcmp(q, "@RELAY.CS.NET") == 0
  446. X     && (r = RDX(p, '%'))) {
  447. X    *RDX(p, '@') = '\0';
  448. X    *r = '@';
  449. X    if (IDX(r, '.') == NULL)
  450. X        Strcat(p, ".CSNET");
  451. X    }
  452. X}
  453. X
  454. X
  455. X/*
  456. X**  Handle hybrid "!" and "@" addresses:
  457. X**    a!site!joe@site --> joe@site
  458. X**    a!site!joe --> joe@site.UUCP
  459. X**    a!site.EDU!joe --> joe@site.EDU
  460. X*/
  461. XSTATIC void
  462. XHybrid(p)
  463. X    register char    *p;
  464. X{
  465. X    register char    *q;
  466. X    register char    *user;
  467. X    char        buff[SM_SIZE];
  468. X
  469. X    if (user = RDX(p, '!')) {
  470. X    *user++ = '\0';
  471. X    if (q = IDX(user, '@'))
  472. X        *q = '\0';
  473. X    q = (q = RDX(p, '!')) ? q + 1 : p;
  474. X    Sprintf(buff, "%s@%s", user, q);
  475. X    if (IDX(q, '.') == NULL)
  476. X        Strcat(buff, ".UUCP");
  477. X    Strcpy(p, buff);
  478. X    }
  479. X}
  480. X
  481. X
  482. X/*
  483. X**  Handle special case for Australia:
  484. X**    user@site.OZ --> user@site.OZ.AU
  485. X*/
  486. XSTATIC void
  487. XEndpart(p)
  488. X    register char    *p;
  489. X{
  490. X    register char    *r;
  491. X
  492. X    if ((r = RDX(p, '.')) && r[1] == 'O' && r[2] == 'Z' && r[3] == '\0')
  493. X    Strcpy(&r[3], ".AU");
  494. X}
  495. X
  496. X
  497. X/*
  498. X**  General address canonicalizer.
  499. X*/
  500. XSTATIC char *
  501. XFixAddress(p)
  502. X    register char    *p;
  503. X{
  504. X    static char        buff[1024];
  505. X    char        host[128];
  506. X
  507. X    if (Local(p)) {
  508. X    if (gethostname(host, sizeof host) < 0) {
  509. X        Fprintf(stderr, "%s:  Can't get my hostname, %s.\n",
  510. X            Pname, strerror(errno));
  511. X        exit(EX_TEMPFAIL);
  512. X    }
  513. X    Sprintf(buff, "%s@%s", p, host);
  514. X    }
  515. X    else {
  516. X    Strcpy(buff, p);
  517. X    Casify(buff);
  518. X    dprintf("   Casify returns %s\n", buff);
  519. X    RouteAddr(buff);
  520. X    dprintf("RouteAddr returns %s\n", buff);
  521. X    Percent(buff);
  522. X    dprintf("  Percent returns %s\n", buff);
  523. X    Csnet(buff);
  524. X    dprintf("    Csnet returns %s\n", buff);
  525. X    Hybrid(buff);
  526. X    dprintf("   Hybrid returns %s\n", buff);
  527. X    Endpart(buff);
  528. X    dprintf("  Endpart returns %s\n", buff);
  529. X    }
  530. X    return buff;
  531. X}
  532. X
  533. X
  534. X/*
  535. X**  This subroutine is a concession to the realities of the Internet and
  536. X**  and the USENET. Much as the idea is distasteful and likely to get me
  537. X**  in trouble, I have to hack message-ids into a format that the USENET
  538. X**  won't choke on.  Pray that if we're doing multiple insertion point
  539. X**  gatewaying that ALL the gateways mung exactly the same things.
  540. X**
  541. X**  (Death to HERMES! Death to UNIX/MM-11! Death to EAN!)
  542. X*/
  543. XSTATIC int
  544. XFixMessageID(s)
  545. X    register char    *s;
  546. X{
  547. X    register int    atdot;
  548. X    register int    closed;
  549. X
  550. X    /* Quickie tests -- why waste time? */
  551. X    if (*s != '<')
  552. X    return FALSE;
  553. X
  554. X    for (atdot = FALSE, closed = FALSE; *++s; )
  555. X    switch (*s) {
  556. X    default:
  557. X        if (!isascii(*s) || iscntrl(*s) || isspace(*s))
  558. X        return FALSE;
  559. X        break;
  560. X    case '<':
  561. X        /* Already got one. */
  562. X        return FALSE;
  563. X    case '>':
  564. X        /* I hope no one is stupid enough to quote this... */
  565. X        closed = TRUE;
  566. X        s[1] = '\0';
  567. X        break;
  568. X    case '.':
  569. X    case '@':
  570. X        /* We should check for a domain spec, not just either/or. */
  571. X        atdot = TRUE;
  572. X        break;
  573. X    case '\t':
  574. X    case ' ':
  575. X    case '/':
  576. X        /* Avoid various problem characters. */
  577. X        *s = '.';
  578. X        break;
  579. X    }
  580. X
  581. X    return atdot && closed;
  582. X}
  583. X
  584. X
  585. X/*
  586. X**  Fix up the contents of In-Reply-To: fields and References: fields.
  587. X*/
  588. XSTATIC void
  589. XFixReferences(hp)
  590. X    register HBUF        *hp;
  591. X{
  592. X    register char        *cp;
  593. X    register char        *ep;
  594. X    register char        *p;
  595. X    register char        *max;
  596. X    char            scratch[LG_SIZE];
  597. X
  598. X    cp = hp->followid;
  599. X    max = cp + strlen(cp);
  600. X    for (p = scratch; cp = IDX(cp, '<'); ) {
  601. X    if ((ep = IDX(cp, '>')) == NULL
  602. X     || ((ep - cp) + 1) > sizeof scratch - (p - scratch + 2))
  603. X        /* Unterminated ID, or no more room. */
  604. X        break;
  605. X
  606. X    if (FixMessageID(cp)) {
  607. X        if (p > scratch) {
  608. X        *p++ = ' ';
  609. X        *p++ = '\0';
  610. X        }
  611. X        p += APPEND(p, cp);
  612. X    }
  613. X    cp = ep + 2;
  614. X    if (cp >= max)
  615. X        break;
  616. X    }
  617. X    Strcpy(hp->followid, scratch);
  618. X}
  619. X
  620. X
  621. X/*
  622. X**  Count the number of '@' in the string.
  623. X*/
  624. XSTATIC int
  625. XAtCount(s)
  626. X    register char    *s;
  627. X{
  628. X    register int    n;
  629. X
  630. X    for (n = 0; *s; s++)
  631. X    if (*s == '@')
  632. X        n++;
  633. X    return n;
  634. X}
  635. X
  636. X
  637. X/*
  638. X**  Canonicalize the "From:" line into the form
  639. X**    From: local-part@domain (full-name)
  640. X** RFC822 doesn't require the comment to be at the end of the string
  641. X** like that.
  642. X*/
  643. XSTATIC void
  644. XFixFrom(hp)
  645. X    register HBUF        *hp;
  646. X{
  647. X    register char        *p;
  648. X    register struct hostent    *host;
  649. X    char            address[LG_SIZE];
  650. X    char            fullname[LG_SIZE];
  651. X    char            scratch[sizeof address];
  652. X
  653. X    /* We should handle "Full-Name:" too, but it doesn't get read by the
  654. X     * news header reader. */
  655. X    (void)CrackFrom(address, fullname, hp->from);
  656. X#ifdef    DO_ADDRESS_CLEANUP
  657. X    Strcpy(address, FixAddress(address));
  658. X#endif    /* DO_ADDRESS_CLEANUP */
  659. X
  660. X    if (AtCount(address) != 1)
  661. X    p = NULL;
  662. X    else {
  663. X    p = IDX(address, '@');
  664. X    *p++ = '\0';
  665. X
  666. X#ifdef    DO_ADDRESS_CLEANUP
  667. X    /* If we can find the host's official name use that. */
  668. X    if (host = gethostbyname(p))
  669. X        p = host->h_name;
  670. X#endif    /* DO_ADDRESS_CLEANUP */
  671. X
  672. X    /* We know have the canonical hostname; glue back together. */
  673. X    Sprintf(scratch, "%s@%s", address, p);
  674. X    Strncpy(address, scratch, sizeof address);
  675. X    address[sizeof address - 1] = '\0';
  676. X    p = IDX(address, '@');
  677. X    *p++ = '\0';
  678. X    }
  679. X
  680. X    /* Policy decision; what to put in the path? */
  681. X#ifdef    FIXED_PATH
  682. X    Strcpy(hp->path, FIXED_PATH);
  683. X#else
  684. X#ifdef    GATEWAY
  685. X    Sprintf(scratch, "%s!%s!%s", GATEWAY, p, address);
  686. X#else
  687. X    Sprintf(scratch, "%s!%s", p, address);
  688. X#endif    /* GATEWAY */
  689. X    Strncpy(hp->path, scratch, sizeof hp->path);
  690. X    hp->path[sizeof hp->path - 1] = '\0';
  691. X#endif    /* FIXED_PATH */
  692. X
  693. X    /* Restore the @ if we took it out. */
  694. X    if (p)
  695. X    *--p = '@';
  696. X
  697. X    if (fullname[0]) {
  698. X    p = address + strlen(address);
  699. X    *p++ = ' ';
  700. X    *p++ = '(';
  701. X    p += APPEND(p, fullname);
  702. X    *p++ = ')';
  703. X    *p++ = '\0';
  704. X    }
  705. X
  706. X    /* Stick the canonicalized From: back in. */
  707. X    Strcpy(hp->from, address);
  708. X}
  709. X
  710. X
  711. X#define ERROR "\
  712. XMessage-ID syntax error.\n\
  713. X*** Please refer to page 23, paragraph 4.6.1. and Appendix D\n\
  714. X*** of NIC RFC #822 for the correct syntax, and fix your mailer."
  715. X
  716. X/*
  717. X** Check an RFC822 header for validity and hack it to RFC1036 spec.
  718. X** returns NULL for everything OK, or a character pointer to an
  719. X** error message.
  720. X*/
  721. Xchar *
  722. XHackHeader(hp, SubjectRequired)
  723. X    register HBUF        *hp;
  724. X    int                SubjectRequired;
  725. X{
  726. X#ifdef    REQUIRE_MESSAGE_ID
  727. X    /* Sendmail (almost) always has a Message-ID */
  728. X    if (hp->ident[0] == '\0')
  729. X    return "Message-ID header missing";
  730. X    if (!FixMessageID(hp->ident))
  731. X    return ERROR;
  732. X#else
  733. X    /* MMDF doesn't always have a Message-ID. */
  734. X    if (hp->ident[0] && !FixMessageID(hp->ident))
  735. X    return ERROR;
  736. X#endif    /* REQUIRE_MESSAGE_ID */
  737. X
  738. X    /* Newsgroups */
  739. X    if (hp->nbuf[0] == '\0')
  740. X    return "Newsgroups header missing";
  741. X
  742. X    /* Subject */
  743. X    if (hp->title[0] == '\0') {
  744. X    if (SubjectRequired)
  745. X        return "Subject header missing";
  746. X    Strcpy(hp->title, "(none)");
  747. X    }
  748. X
  749. X    /* From */
  750. X    if (hp->from[0] == '\0')
  751. X    return "From header missing";
  752. X    FixFrom(hp);
  753. X
  754. X    /* References and In-Reply-To */
  755. X    if (hp->followid[0]) 
  756. X    FixReferences(hp);
  757. X
  758. X    return NULL;
  759. X}
  760. X
  761. X
  762. X#ifdef    TEST
  763. Xmain()
  764. X{
  765. X    char    buff[256];
  766. X    int        i;
  767. X
  768. X    if (i = isatty(0))
  769. X    (void)printf("Enter addresses:\n");
  770. X    for ( ; ; ) {
  771. X    if (i)
  772. X        (void)printf(">  ");
  773. X    if (gets(buff) == NULL || buff[0] == '\0')
  774. X        break;
  775. X    if (buff[0] != '#')
  776. X        (void)printf("\t%s -> %s\n\n", buff, FixAddress(buff));
  777. X    }
  778. X
  779. X    exit(0);
  780. X}
  781. X#endif    /* TEST */
  782. END_OF_FILE
  783.   if test 10652 -ne `wc -c <'hdr.c'`; then
  784.     echo shar: \"'hdr.c'\" unpacked with wrong size!
  785.   fi
  786.   # end of 'hdr.c'
  787. fi
  788. if test -f 'lex.l' -a "${1}" != "-c" ; then 
  789.   echo shar: Will not clobber existing file \"'lex.l'\"
  790. else
  791.   echo shar: Extracting \"'lex.l'\" \(3664 characters\)
  792.   sed "s/^X//" >'lex.l' <<'END_OF_FILE'
  793. X/*
  794. X**  Lexical analyzer for the gag language.  We have our own FSA
  795. X**  for comments because it's much smaller and quicker that way.
  796. X*/
  797. X%{
  798. X#include "gate.h"
  799. X#include "gag.h"
  800. X
  801. X/* State of our automaton. */
  802. Xtypedef enum _STATE {
  803. X    S_STAR, S_NORMAL, S_END
  804. X} STATE;
  805. X
  806. X/* Key-value pair. */
  807. Xtypedef struct _PAIR {
  808. X    char    *name;
  809. X    int        value;
  810. X} PAIR;
  811. X
  812. Xchar        yyfilename[SM_SIZE];
  813. Xextern int    Errors;
  814. X
  815. X/* List of GAG's keywords. */
  816. XSTATIC PAIR    Keywords[] = {
  817. X    {    "default",        tDEFAULT    },
  818. X    {    "directory",        tDIRECTORY    },
  819. X    {    "distributions",    tDISTRIBUTIONS    },
  820. X    {    "dotify",        tDOTIFY        },
  821. X    {    "false",        tFALSE        },
  822. X    {    "flags",        tFLAGS        },
  823. X    {    "gateway",        tGATEWAY    },
  824. X    {    "inews",        tINEWS        },
  825. X    {    "mail2news",        tMAIL2NEWS    },
  826. X    {    "mailcontact",        tMAILCONTACT    },
  827. X    {    "mailhost",        tMAILHOST    },
  828. X    {    "mailinglist",        tMAILINGLIST    },
  829. X    {    "mailpost",        tMAILPOST    },
  830. X    {    "moderator",        tMODERATOR    },
  831. X    {    "news2mail",        tNEWS2MAIL    },
  832. X    {    "organization",        tORGANIZATION    },
  833. X    {    "owner",        tOWNER        },
  834. X    {    "request_address",    tREQUESTADDR    },
  835. X    {    "site",            tSITE        },
  836. X    {    "true",            tTRUE        },
  837. X    {    "user",            tUSER        },
  838. X    {    NULL,            0        }
  839. X};
  840. X
  841. X%}
  842. X
  843. X%%
  844. X
  845. X[-+0-9A-Za-z_.]+    {
  846. X            /* A simple tID or keyword. */
  847. X            register PAIR    *p;
  848. X
  849. X            /* Keyword? */
  850. X            for (p = Keywords; p->name; p++)
  851. X            if (EQ(p->name, yytext))
  852. X                return p->value;
  853. X            yylval.String = COPY(yytext);
  854. X            return tID;
  855. X        }
  856. X
  857. X^#[ \t]+[0-9]+[ \t]+"[^\n]+"[^\n]*$    {
  858. X            /* C pre-processor control line. */
  859. X            register char    *p;
  860. X            char        *namep;
  861. X
  862. X            /* Find the line number. */
  863. X            for (p = yytext; *p && !isdigit(*p); p++)
  864. X            ;
  865. X            /* Parse the number, find the start of the filename. */
  866. X            for (yylineno = atoi(p); *p && *p != '"'; p++)
  867. X            ;
  868. X            /* March down to the end of the filename. */
  869. X            for (namep = p; *++p && *p != '"'; p++)
  870. X            ;
  871. X            *p = '\0';
  872. X            (void)strncpy(yyfilename, namep, sizeof yyfilename - 1);
  873. X            yyfilename[sizeof yyfilename - 1] = '\0';
  874. X        }
  875. X
  876. X\"[^"]*        {
  877. X            /* Quoted string. */
  878. X            int        c;
  879. X
  880. X            /* See the Lex paper in Volume 2A or PS1:16
  881. X             * for details on this code. */
  882. X            if (yytext[yyleng - 1] == '\\')
  883. X            yymore();
  884. X            else {
  885. X            if ((c = input()) == '"') {
  886. X                yylval.String = COPY(&yytext[1]);
  887. X                return tID;
  888. X            }
  889. X            unput(c);
  890. X            yyerror("Bad string");
  891. X            }
  892. X        }
  893. X
  894. X"/*"            {
  895. X            /* Comment. */
  896. X            register STATE    S;
  897. X
  898. X            for (S = S_NORMAL; S != S_END; )
  899. X            switch (input()) {
  900. X            case '/':
  901. X                if (S == S_STAR) {
  902. X                S = S_END;
  903. X                break;
  904. X                }
  905. X                /* FALLTHROUGH */
  906. X            default:
  907. X                S = S_NORMAL;
  908. X                break;
  909. X            case '\0':
  910. X                S = S_END;
  911. X                break;
  912. X            case '*':
  913. X                S = S_STAR;
  914. X                break;
  915. X            }
  916. X        }
  917. X
  918. X[ \t\n]        {
  919. X            /* Tasty whitespace. */
  920. X#ifdef    lint
  921. X            /* I am compulsive about lint natterings. */
  922. X            yytext[0] = yyinput();
  923. X            yyoutput(yytext[0]);
  924. X            yyunput(yytext[0]);
  925. X            REJECT;
  926. X#endif    /* lint */
  927. X        }
  928. X
  929. X.        {
  930. X            /* Random special character. */
  931. X            return *yytext;
  932. X        }
  933. X
  934. X%%
  935. X
  936. X
  937. X/*
  938. X**  Called by lex at end-of-stream.  Return one if no more input.
  939. X*/
  940. Xint
  941. Xyywrap()
  942. X{
  943. X    return 1;
  944. X}
  945. X
  946. X
  947. Xyyopen(p)
  948. X    char    *p;
  949. X{
  950. X    if (p == NULL)
  951. X    (void)strcpy(yyfilename, "stdin");
  952. X    else {
  953. X    if ((yyin = fopen(p, "r")) == NULL) {
  954. X        Fprintf(stderr, "%s: Can't open \"%s\" for input, %s.\n",
  955. X            Pname, p, strerror(errno));
  956. X        exit(1);
  957. X    }
  958. X    (void)strcpy(yyfilename, p);
  959. X    }
  960. X}
  961. X
  962. X
  963. X/*
  964. X**  Write an error message.
  965. X*/
  966. Xyyerror(p)
  967. X    char    *p;
  968. X{
  969. X    char    buff[SM_SIZE];
  970. X
  971. X    (void)strncpy(buff, yytext, sizeof buff);
  972. X    buff[sizeof buff - 1] = '\0';
  973. X    Fprintf(stderr, "\"%s\", line %d: %s (near \"%s\")\n",
  974. X        yyfilename, yylineno, p, buff);
  975. X    Errors++;
  976. X}
  977. END_OF_FILE
  978.   if test 3664 -ne `wc -c <'lex.l'`; then
  979.     echo shar: \"'lex.l'\" unpacked with wrong size!
  980.   fi
  981.   # end of 'lex.l'
  982. fi
  983. if test -f 'mail-interface' -a "${1}" != "-c" ; then 
  984.   echo shar: Will not clobber existing file \"'mail-interface'\"
  985. else
  986.   echo shar: Extracting \"'mail-interface'\" \(2823 characters\)
  987.   sed "s/^X//" >'mail-interface' <<'END_OF_FILE'
  988. X#! /bin/sh
  989. X##  A portable mail interface program.  Original by Piete Brooks,
  990. X##  modified by Rich $alz <rsalz@bbn.com>
  991. X
  992. Xmailer="${mailer-/usr/lib/sendmail}"
  993. Xheaders=false
  994. X
  995. X##  Decode the arguments.
  996. Xwhile test $# -gt 0 ; do
  997. X    arg="$1"
  998. X    shift
  999. X    case "$arg" in
  1000. X    -A|-ASIS)
  1001. X    asis=true
  1002. X    ;;
  1003. X    -b|-body)
  1004. X    body="$body
  1005. X$1"
  1006. X    shift
  1007. X    ;;
  1008. X    -c|-cc)
  1009. X    cc="$cc, $1"
  1010. X    shift
  1011. X    headers=true
  1012. X    ;;
  1013. X    -f|-from)
  1014. X    from="$1"
  1015. X    shift
  1016. X    headers=true
  1017. X    ;;
  1018. X    -h|-help)
  1019. X    cat <<EOF
  1020. XUsage: $0 [flags] [recipients...]
  1021. X    -A -ASIS    Send text ASIS, i.e. headers are present in the input
  1022. X    -b -body    String which is to be the body of the message
  1023. X    -c -cc        Carbon Copy recipients
  1024. X    -f -from    From field
  1025. X    -h -help    This message
  1026. X    -r -recip    Recipient (passed on command line)
  1027. X    -s -subject    Set the subject field
  1028. X    -t -to        Main recipients
  1029. X    -*        ERROR
  1030. X    *        treat as recipients
  1031. XEOF
  1032. X    exit 1
  1033. X    ;;
  1034. X    -r|-recip)
  1035. X    recip="$recip $1"
  1036. X    shift
  1037. X    ;;
  1038. X    -s|-subject)
  1039. X    subject="$subject, $1"
  1040. X    shift
  1041. X    headers=true
  1042. X    ;;
  1043. X    -t|-to)
  1044. X    to="$to, $1"
  1045. X    shift
  1046. X    headers=true
  1047. X    ;;
  1048. X    -*)
  1049. X    echo $0: invalid argument \""$arg"\"
  1050. X    exit 1
  1051. X    ;;
  1052. X    *)
  1053. X    to="$to, $arg"
  1054. X    ;;
  1055. X    esac
  1056. Xdone
  1057. X
  1058. X##  If no recipients, send to postmaster.
  1059. Xcase "$to$cc$recip" in
  1060. X'')
  1061. X    recip=postmaster
  1062. X    ;;
  1063. Xesac
  1064. X
  1065. X##  If we got no headers on the command line, read them from the message.
  1066. Xcase $headers in
  1067. Xfalse)
  1068. X    asis=true
  1069. X    ;;
  1070. Xesac
  1071. X
  1072. X##  Strip off the spurious leading ", " in repeatable items
  1073. Xcase "$to" in
  1074. X', '*)
  1075. X    to=`expr "$to" : ", \(.*\)`
  1076. X    ;;
  1077. Xesac
  1078. Xcase "$cc"  in
  1079. X', '*)
  1080. X    cc=`expr "$cc" : ", \(.*\)`
  1081. X    ;;
  1082. Xesac
  1083. Xcase "$subject"    in ', '*)
  1084. X    subject=`expr "$subject" : ", \(.*\)`
  1085. X    ;;
  1086. Xesac
  1087. X
  1088. X##  Now do the business.
  1089. Xcase "$mailer" in
  1090. X*/sendmail|sendmail|*/sendmail' '*|sendmail' '*)
  1091. X    args="-oi"
  1092. X    if [ -z "$recip" ] ; then
  1093. X    args="$args -t"
  1094. X    fi
  1095. X    (
  1096. X    if [ ! -z "$subject" ] ; then
  1097. X        echo "Subject: $subject"
  1098. X    fi
  1099. X    if [ ! -z "$from" ] ; then
  1100. X        echo "From: $from"
  1101. X    fi
  1102. X    if [ ! -z "$to" ] ; then
  1103. X        echo "To: $to"
  1104. X    fi
  1105. X    if [ ! -z "$cc" ] ; then
  1106. X        echo "Cc: $cc"
  1107. X    fi
  1108. X    if [ -z "$asis" ] ; then
  1109. X        echo ""
  1110. X    fi
  1111. X    if [ -z "$body" ] ; then
  1112. X        cat
  1113. X    else
  1114. X        echo "$body" | sed 1d
  1115. X    fi
  1116. X    ) | $debug $mailer $args $recip
  1117. X    ;;
  1118. X
  1119. X*/submit|submit|*/submit' '*|submit' '*)
  1120. X    args="-tsz"
  1121. X    case "$recip" in
  1122. X    if [ -z "$recip" ] ; then
  1123. X    if [ ! -z "$to" ] ; then
  1124. X        args="${args}gto*"
  1125. X    fi
  1126. X    if [ ! -z "$cc" ] ; then
  1127. X        args="${args}gcc*"
  1128. X    fi
  1129. X    fi
  1130. X    (
  1131. X    if [ ! -z "$subject" ] ; then
  1132. X        echo "Subject: $subject"
  1133. X    fi
  1134. X    if [ ! -z "$from" ] ; then
  1135. X        echo "From: $from"
  1136. X    fi
  1137. X    if [ ! -z "$to" ] ; then
  1138. X        echo "To: $to"
  1139. X    fi
  1140. X    if [ ! -z "$cc" ] ; then
  1141. X        echo "Cc: $cc"
  1142. X    fi
  1143. X    if [ -z "$asis" ] ; then
  1144. X        echo ""
  1145. X    fi
  1146. X    if [ -z "$body" ] ; then
  1147. X        cat
  1148. X    else
  1149. X        echo "$body" | sed 1d
  1150. X    fi
  1151. X    ) | $debug $mailer $args $recip
  1152. X    ;;
  1153. X
  1154. X*)
  1155. X    echo Unknown mailer 1>&2
  1156. X    exit 1
  1157. X    ;;
  1158. X
  1159. Xesac
  1160. END_OF_FILE
  1161.   if test 2823 -ne `wc -c <'mail-interface'`; then
  1162.     echo shar: \"'mail-interface'\" unpacked with wrong size!
  1163.   fi
  1164.   # end of 'mail-interface'
  1165. fi
  1166. if test -f 'mail2news.1' -a "${1}" != "-c" ; then 
  1167.   echo shar: Will not clobber existing file \"'mail2news.1'\"
  1168. else
  1169.   echo shar: Extracting \"'mail2news.1'\" \(5516 characters\)
  1170.   sed "s/^X//" >'mail2news.1' <<'END_OF_FILE'
  1171. X.\" $Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/mail2news.1,v 1.11 91/02/12 14:46:17 rsalz Exp $
  1172. X.TH MAIL2NEWS 1 LOCAL
  1173. X.SH NAME
  1174. Xmail2news \- feed a mail message into Usenet news
  1175. X.SH SYNOPSIS
  1176. X.B mail2news
  1177. X[
  1178. X.B \-\&.
  1179. X] [
  1180. X.B \-F
  1181. X] [
  1182. X.BI \-= program
  1183. X] [
  1184. X.BI \-n newsgroups
  1185. X] [
  1186. X.BI \-o organization
  1187. X] [
  1188. X.B inewsflags
  1189. X]
  1190. X.SH DESCRIPTION
  1191. X.I Mail2news
  1192. Xreads an RFC822 Mail message on standard input, writes the headers to conform
  1193. Xwith RFC1036 (superceeding RFC850) Usenet News article.
  1194. XA subject is required, unless one of the
  1195. X.IR inews (8)
  1196. X``\-x'' or ``\-o'' flags are specified
  1197. X(these flags are recognized by
  1198. X.I mail2news
  1199. Xbefore being passed on to
  1200. X.IR inews ).
  1201. X.PP
  1202. XIf the ``\-.'' flag is specified, the modified article is sent to the
  1203. Xstandard output, rather than feed into
  1204. X.IR inews .
  1205. X.PP
  1206. XBy default,
  1207. X.I mail2news
  1208. Xsends its input to ``inews \-h''; this can be changed by using the ``\-=''
  1209. Xflag, which will send the output to the specified program.
  1210. XNote that no argument parsing is done, so that only a single word may
  1211. Xbe specified with the ``\-='' flag.
  1212. X.PP
  1213. XThe options used by
  1214. X.I mail2news
  1215. Xare typically punctuation characters, to avoid conflicts with any letters
  1216. Xthat might be used by
  1217. X.I inews
  1218. Xor any other news-processing program.
  1219. X.PP
  1220. XAs a concession to
  1221. X.IR sendmail (8)
  1222. Xalias processing the argument to the ``\-o'' flag is handled specially.
  1223. XSince many
  1224. X.I sendmail.cf
  1225. Xfiles do not have the ``preserve case'' flag on for the ``prog'' mailer,
  1226. Xa period in the argument means that the following character should be converted
  1227. Xto uppercase; two periods mean to output a single period.
  1228. XFor example, if the following line is in
  1229. X.IR /usr/lib/aliases (5):
  1230. X.RS
  1231. Xpost\-news\-admin:
  1232. X    "|/usr/local/bin/mail2news \-o '.the .b...b...n.. .gateway' \-n news.admin"
  1233. X.RE
  1234. Xthen messages to mailed to
  1235. X.I post\-news\-admin
  1236. Xwill be posted to the ``news.admin'' newsgroup with the following header line:
  1237. X.RS
  1238. XOrganization: The B.B.N. Gateway
  1239. X.RE
  1240. X.PP
  1241. XIf the ``\-F'' flag is given, then
  1242. X.I mail2news
  1243. Xwill try to filter out
  1244. Xthe ``please add me to your mailing list'' messages often sent by
  1245. Xnetwork neophytes.
  1246. XThis is done by looking for short messages which have words like
  1247. X.I subscribe
  1248. Xin them.
  1249. X.PP
  1250. X.I Mail2news
  1251. Xcan modify the newsgroups an article is sent to, based on regular expressions
  1252. Xfound in the ``Title:'', ``Keywords:'', and ``Summary:'' headers.
  1253. XThe headers are scanned once for each newsgroup the article is originally
  1254. Xdestined for, provided a mapping file exists for the newsgroup.
  1255. X(The path to the mapping file depends on a compile\-time parameter.)
  1256. XFor example, if a mail message is to be sent to
  1257. X.I talk.foo
  1258. Xand
  1259. X.IR soc.bar ,
  1260. X.I mail2news
  1261. Xwill scan the headers twice.
  1262. XIf the file
  1263. X.I /usr/lib/news/.admin/talk.foo
  1264. X(or
  1265. X.IR /usr/spool/news/talk/foo/recnews.cmd )
  1266. Xexists, the commands in that file are interpreted.
  1267. XThe scan is repeated, with the appropriate file for
  1268. X.IR soc.bar .
  1269. XIn the explanation below, the ``current newsgroup'' will be first
  1270. X.I talk.foo
  1271. Xand then
  1272. X.IR soc.bar .
  1273. X.PP
  1274. XBlank lines, and lines beginning with a pound sign
  1275. X.RI ( # )
  1276. Xare ignored.
  1277. XOther lines should like like this:
  1278. X.RS
  1279. X.IR "delim pattern delim command whitespace " "[" "arg" "]"
  1280. X.RE
  1281. XThe
  1282. X.I delim
  1283. Xcan be any character; if it appears in the pattern, it should be
  1284. Xpreceeded by a backslash
  1285. X.RI ( \e ).
  1286. XThe
  1287. X.I pattern
  1288. Xis an
  1289. X.RI `` ed (1)\-style''
  1290. Xregular expression, as detailed in the
  1291. X.IR regex (3L)
  1292. Xmanual page.
  1293. XThe
  1294. X.I command
  1295. Xis a single letter from the set
  1296. X.RI [ adkmq ],
  1297. Xand is described below.
  1298. XThe
  1299. X.I whitespace
  1300. Xis, obviously, any combination of spaces and tabs.
  1301. XFinally, the optional
  1302. X.I arg
  1303. Xshould be a comma\-separated list of newsgroups to be acted on by the
  1304. Xcommand.
  1305. X.PP
  1306. XThe valid commands are:
  1307. X.RS
  1308. X.nf
  1309. X.ta \w'm      'u +\w'Quiet kill    'u
  1310. Xa    Add    All newsgroups in the arg are added
  1311. Xd    Delete    The current group is deleted from the article
  1312. Xk    Kill    The article is returned, and arg is given as a contact name
  1313. Xm    Move    The current group is deleted and the arg group is added
  1314. Xq    Quiet kill    The article is quietly ignored
  1315. X.fi
  1316. X.RE
  1317. X.PP
  1318. XFor example, here is a fragment from the mapping file for a
  1319. X.I local.bboard
  1320. Xnewsgroup:
  1321. X.RS
  1322. X.nf
  1323. X.ta \w'/apartment/m   'u
  1324. X# Move seminars and talks
  1325. X/seminar/m    local.seminars,region.seminars
  1326. X/lecture/m    local.seminars,region.seminars
  1327. X# Move housing requests
  1328. X/housing/m    local.housing
  1329. X/apartment/m    local.housing
  1330. X# Kill flames
  1331. X/flame/k    the anti-flame society
  1332. X/jerk/q    @placeholder
  1333. X# Copy machine downtime announcements
  1334. X/downtime/a    local.config,news.config
  1335. X# If you want something, it's not forsale
  1336. X/want/a        local.wanted
  1337. X/want/d        @placeholder
  1338. X.fi
  1339. X.RE
  1340. XThe last two lines show how one might tweak cross\-posts, if the mapping
  1341. Xfile were for a
  1342. X.I local.wanted
  1343. Xnewsgroup.
  1344. X.SH DIAGNOSTICS
  1345. XAlmost all return values from system calls and standard I/O library routines
  1346. Xare checked.
  1347. XIf anything goes wrong, a diagnostic message is sent to standard error, where
  1348. Xit will presumably be picked up by
  1349. X.I sendmail
  1350. X(or other mail-processing program) and returned to the originator, who will
  1351. Xin turn be confused because she doesn't know anything at all about this
  1352. Xgateway program.
  1353. X.SH FILES
  1354. X.ta \w'uucp\-2\-inet  'u
  1355. Xuucp\-2\-inet    Mapping of ``Path:'' names to Internet hostnames.
  1356. X.br
  1357. Xinews    News delivery program.
  1358. X.br
  1359. XThe full paths to these files are compile\-time constants; see
  1360. X.I gate.h
  1361. Xin the source for the exact details.
  1362. X.SH "SEE ALSO"
  1363. Xgag(1L), mkmailpost(1L), news2mail(1L).
  1364. X.SH AUTHORS
  1365. XRich $alz <rsalz@bbn.com>, after
  1366. X.I nrecnews
  1367. Xby
  1368. X.br
  1369. XErik E. Fair <fair@apple.com>.
  1370. X.br
  1371. XOzan Yigit <yunexus!oz> wrote the regular\-expression routines.
  1372. END_OF_FILE
  1373.   if test 5516 -ne `wc -c <'mail2news.1'`; then
  1374.     echo shar: \"'mail2news.1'\" unpacked with wrong size!
  1375.   fi
  1376.   # end of 'mail2news.1'
  1377. fi
  1378. if test -f 'misc.c' -a "${1}" != "-c" ; then 
  1379.   echo shar: Will not clobber existing file \"'misc.c'\"
  1380. else
  1381.   echo shar: Extracting \"'misc.c'\" \(2955 characters\)
  1382.   sed "s/^X//" >'misc.c' <<'END_OF_FILE'
  1383. X/*
  1384. X**  Miscellaneous routines.
  1385. X*/
  1386. X#include "gate.h"
  1387. X#ifdef    RCSID
  1388. Xstatic char RCS[] =
  1389. X    "$Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/misc.c,v 1.7 91/02/12 14:47:53 rsalz Exp $";
  1390. X#endif    /* RCSID */
  1391. X
  1392. X
  1393. X/*
  1394. X**  Allocate memory.
  1395. X*/
  1396. Xalign_t
  1397. XMyAlloc(i)
  1398. X    int            i;
  1399. X{
  1400. X    align_t        p;
  1401. X
  1402. X    if ((p = (align_t)malloc((unsigned int)i)) == NULL) {
  1403. X    Fprintf(stderr, "%s:  Could not allocate %d bytes: %s\n",
  1404. X        Pname, i, strerror(errno));
  1405. X    exit(EX_OSERR);
  1406. X    }
  1407. X    return p;
  1408. X}
  1409. X
  1410. X
  1411. X#ifndef    HAVE_STRERROR
  1412. X/*
  1413. X**  Return a printable representation of errno.
  1414. X*/
  1415. Xchar *
  1416. Xstrerror(x)
  1417. X    int            x;
  1418. X{
  1419. X    static char        buff[20];
  1420. X
  1421. X    if (x >= 0 && x < sys_nerr)
  1422. X    return sys_errlist[x];
  1423. X    Sprintf(buff, "Error code %d", x);
  1424. X    return buff;
  1425. X}
  1426. X#endif    /* HAVE_STRERROR */
  1427. X
  1428. X
  1429. X/*
  1430. X**  Free up something that Split() made.
  1431. X*/
  1432. Xvoid
  1433. XSplitFree(p)
  1434. X    char    ***p;
  1435. X{
  1436. X    if (p && *p) {
  1437. X    free((*p)[0]);
  1438. X    free((char *)*p);
  1439. X    *p = NULL;
  1440. X    }
  1441. X}
  1442. X
  1443. X
  1444. X/*
  1445. X**  This is an AWK-style split routine.  If the split character is NULL,
  1446. X**  we split on space or tab and eat long stretches of same (that is, no
  1447. X**  null fields will result).  Returns number of fields made.
  1448. X*/
  1449. Xint
  1450. XSplit(s, p, c)
  1451. X    register char    *s;
  1452. X    char        ***p;
  1453. X    register char    c;
  1454. X{
  1455. X    register char    *cp;
  1456. X    register int    blank;
  1457. X    register int    n;
  1458. X    register int    i;
  1459. X
  1460. X    if (s == NULL || *s == '\0') {
  1461. X    Fprintf(stderr, "%s:  Someone was a pinhead!\n", Pname);
  1462. X    abort();
  1463. X    }
  1464. X
  1465. X    i = strlen(s) + 1;
  1466. X    cp = NEW(char, i);
  1467. X    /* This is too much -- we'll realloc what we really need later. */
  1468. X    *p = NEW(char*, i);
  1469. X
  1470. X    if (c == '\0') {
  1471. X    /* Eat multiple whitespace characters. */
  1472. X    for (blank = TRUE, n = 0; *s; s++)
  1473. X        if (WHITE(*s)) {
  1474. X        if (!blank)
  1475. X            *cp++ = '\0';
  1476. X        blank = TRUE;
  1477. X        }
  1478. X        else {
  1479. X        if (blank)
  1480. X            (*p)[n++] = cp;
  1481. X        *cp++ = *s;
  1482. X        blank = FALSE;
  1483. X        }
  1484. X
  1485. X    if (n == 0) {
  1486. X        (*p)[0] = cp;
  1487. X        SplitFree(p);
  1488. X        return 0;
  1489. X    }
  1490. X    }
  1491. X    else
  1492. X    /* Normal case: find all occurrences of "c" and null them as field
  1493. X     * terminators; add new string starts to the array of pointers to
  1494. X     * strings. */
  1495. X    for ((*p)[0] = cp, n = 1; *s; s++)
  1496. X        if (*s == c) {
  1497. X        *cp++ = '\0';
  1498. X        (*p)[n++] = cp;
  1499. X        }
  1500. X        else
  1501. X        *cp++ = *s;
  1502. X
  1503. X    /* Free up the excess space. */
  1504. X    *p = (char **)REALLOC(*p, (n + 1) * sizeof (char *));
  1505. X    (*p)[n] = NULL;
  1506. X    return n;
  1507. X}
  1508. X
  1509. X
  1510. X
  1511. X/*
  1512. X**  Read in a file of lines, dump it into an array of strings.
  1513. X*/
  1514. Xchar **
  1515. XReadFile(Name)
  1516. X    char        *Name;
  1517. X{
  1518. X    register FILE    *F;
  1519. X    register char    **v;
  1520. X    register char    *p;
  1521. X    register int    i;
  1522. X    char        **value;
  1523. X    char        buff[SM_SIZE];
  1524. X
  1525. X    /* Open file, count number of lines therein. */
  1526. X    if ((F = fopen(Name, "r")) == NULL) {
  1527. X    perror(Name);
  1528. X    exit(EX_OSFILE);
  1529. X    }
  1530. X    for (i = 1; fgets(buff, sizeof buff, F); i++)
  1531. X    ;
  1532. X
  1533. X    rewind(F);
  1534. X    for (v = value = NEW(char*, i); fgets(buff, sizeof buff, F); ) {
  1535. X    if (p = IDX(buff, '\n'))
  1536. X        *p = '\0';
  1537. X    if (buff[0] && buff[0] != '#')
  1538. X        *v++ = COPY(buff);
  1539. X    }
  1540. X
  1541. X    *v = NULL;
  1542. X    return value;
  1543. X}
  1544. END_OF_FILE
  1545.   if test 2955 -ne `wc -c <'misc.c'`; then
  1546.     echo shar: \"'misc.c'\" unpacked with wrong size!
  1547.   fi
  1548.   # end of 'misc.c'
  1549. fi
  1550. if test -f 'news2mail.1' -a "${1}" != "-c" ; then 
  1551.   echo shar: Will not clobber existing file \"'news2mail.1'\"
  1552. else
  1553.   echo shar: Extracting \"'news2mail.1'\" \(5362 characters\)
  1554.   sed "s/^X//" >'news2mail.1' <<'END_OF_FILE'
  1555. X.\" $Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/news2mail.1,v 1.7 91/02/12 14:49:43 rsalz Exp $
  1556. X.TH NEWS2MAIL 1 LOCAL
  1557. X.SH NAME
  1558. Xnews2mail \- feed a Usenet news article to mail
  1559. X.SH SYNOPSIS
  1560. X.B news2mail
  1561. X[
  1562. X.BI \-E var=value
  1563. X] [
  1564. X.B \-.
  1565. X]
  1566. Xlistname listaddr listadmin host [ article ]
  1567. X.SH DESCRIPTION
  1568. X.PP
  1569. X.I News2mail
  1570. Xreads a news article edits the headers to make it look like an RFC822 mail
  1571. Xmessage.
  1572. XIt feeds the results to
  1573. Xand feeds it to
  1574. X.IR sendmail (8),
  1575. X.IR MMDF (8),
  1576. Xor a shell script.
  1577. XIf the ``\-.'' flag is used, then the results are sent to standard output,
  1578. Xfor debugging.
  1579. X.PP
  1580. XThe article is taken from the file specified on the command line, or read
  1581. Xfrom standard input if not specified.
  1582. X.PP
  1583. XThe ``\-E'' flag can be used to set environment variables for the delivery
  1584. Xprogram that is invoked.
  1585. XThey should be of the form ``name=value'' as in
  1586. X\&``\-E mailer=/usr/lib/pp/cmds/submit''.
  1587. X.PP
  1588. X.I News2mail
  1589. Xswallows control messages,
  1590. Xremoves all but the last three entries from the ``References'' header,
  1591. Xand merges the ``From'' and ``Path'' headers to build a single
  1592. X``From'' header for the mail message (see below).
  1593. XThe ``Date,'' ``Subject,'' ``Reply\-To,'' ``Message\-ID,'' and ``Organization''
  1594. Xheaders are passed through unchanged.
  1595. XAny other headers in the original input are removed.
  1596. X.PP
  1597. XTo ``To,'' and ``Sender'' headers and the SMTP destination envelope are set
  1598. Xaccording to the parameters specified on the command line.
  1599. XThe ``To'' header is set to be \fIlistname\fP, with \fI@host\fP appended if there
  1600. Xis no atsign in \fIlistname\fP.
  1601. XThis should contain the name of the mailing list.
  1602. XThe mail is actually sent to \fIlistaddr\fP by specifying it as the
  1603. Xrecipient in the mailer command line.
  1604. X(If \fIlistaddr\fP does not have an atsign, then \fIlistaddr@host\fP is used.)
  1605. XBy treating the ``To'' header and the destination envelope separately,
  1606. Xother members of the mailing list can properly reply to the messages that
  1607. Xpass through
  1608. X.IR news2mail .
  1609. XIn addition, \fIlistaddr\fP can be an address that sends to everyone on
  1610. Xthe list except the gateway.
  1611. XThis is an optimization, however, because
  1612. X.IR inews (8)
  1613. Xwill reject any Message-ID that it has already seen.
  1614. X.PP
  1615. XThe ``Sender'' header is set to be \fIlistadmin\fP, with \fI@host\fP
  1616. Xappended if there is no atsign in \fIlistadmin\fP.
  1617. XThese values should correspond to the maintainer of the mailing list.
  1618. XSome mailers will also automatically fill in the ``Return-Path'' header
  1619. Xwith this value.
  1620. X.PP
  1621. XThe goal of the header manipulations is to send the news article to all
  1622. Xrecipient of the mailing list, but with the headers set so that delivery
  1623. Xerrors are sent to the list maintainer for disposition.
  1624. X.PP
  1625. X.IR Mail2news
  1626. Xtries to shrink the ``Path'' header by taking note of neighboring
  1627. X\s-2UUCP\s0 hosts and scanning for other Internet hosts that it can
  1628. Xshort\-circuit to.
  1629. X.IR Uuname (1)
  1630. Xis used to check for \s-2UUCP\s0 neighbors; the file
  1631. X.I uucp\-2\-inet
  1632. Xis read to map \s-2UUCP\s0 names to Internet domain names.
  1633. XFor efficiency,
  1634. X.I mail2news
  1635. Xstores
  1636. X.IR uuname 's
  1637. Xoutput in a private file, and will only call
  1638. X.I uuname
  1639. Xif the file is older than the \s-2UUCP\s0
  1640. X.IR L.sys (5)
  1641. Xfile.
  1642. X.PP
  1643. XIn order to have
  1644. X.I sendmail
  1645. Xbelieve that the headers it has created are valid,
  1646. X.I news2mail
  1647. Xmust be able to 
  1648. X.IR setuid (2)
  1649. Xto one of
  1650. X.IR sendmail 's
  1651. Xtrusted users.
  1652. X.SH EXAMPLE
  1653. X.PP
  1654. XSuppose the following article arrives
  1655. X.IR comp.sources.unix\| :
  1656. X.RS
  1657. X.nf
  1658. XPath: bbn!husc6!uunet!rsalz
  1659. XFrom: rsalz@uunet.UU.NET (Rich Salz)
  1660. XNewsgroups: comp.sources.unix
  1661. XSubject: v10INF1:  Introduction to comp.sources.unix
  1662. XMessage\-ID: <830@uunet.UU.NET>
  1663. XDate: 10 Aug 87 21:57:17 GMT
  1664. XExpires: 10 Nov 87 22:17:17 GMT
  1665. XOrganization: UUNET Communications Services, Arlington, VA
  1666. XLines: 189
  1667. XApproved: rsalz@uunet.UU.NET
  1668. X
  1669. XThis is the first of two introductory articles about comp.sources.unix.
  1670. X\&...
  1671. X.fi
  1672. X.RE
  1673. XAlso, assume the following line is in your news sys file (see
  1674. X.IR news (5)):
  1675. X.RS
  1676. X.nf
  1677. Xgateway:world,comp.sources.unix::\e
  1678. X.ti +.5i
  1679. Xnews2mail unix\-sources rsalz unix\-sources\-request bbn.com
  1680. X.fi
  1681. X.RE
  1682. XThe
  1683. X.I news2mail
  1684. Xprogram would generate the following article and feed it to
  1685. X.IR sendmail :
  1686. X.RS
  1687. X.nf
  1688. XReceived: from USENET by bbn.com with netnews
  1689. X    for rsalz@bbn.com (unix\-sources@bbn.com);
  1690. X    contact usenet@bbn.com if you have questions.
  1691. XTo: unix\-sources@bbn.com
  1692. XDate: 10 Aug 87 21:57:17 GMT
  1693. XFrom: rsalz@uunet.uu.net (Rich Salz)
  1694. XSender: unix\-sources\-request@bbn.com
  1695. XSubject: v10INF1:  Introduction to comp.sources.unix
  1696. XMessage\-ID: <830@uunet.UU.NET>
  1697. XOrganization: UUNET Communications Services, Arlington, VA
  1698. X
  1699. XThis is the first of two introductory articles about comp.sources.unix.
  1700. X\&...
  1701. X.fi
  1702. X.RE
  1703. X.SH DIAGNOSTICS
  1704. XMost return values from I/O routines are checked; if anything goes
  1705. Xwrong, a diagnostic message is sent to a log file.
  1706. XThis file will occasionally have to be examined and trimmed.
  1707. X.SH FILES
  1708. X.ta \w'news2mail.out  'u
  1709. Xnews2mail.out    Error log (standard error)
  1710. X.br
  1711. Xuucp\-2\-inet    Mapping of ``Path'' names to Internet hostnames.
  1712. X.br
  1713. Xuuname.out    Last output from
  1714. X.IR uuname .
  1715. X.br
  1716. XThe full paths to these files are compile\-time constants; see
  1717. X.I gate.h
  1718. Xin the source for the exact details.
  1719. X.SH "SEE ALSO"
  1720. Xgag(1L), mail2news(1L).
  1721. X.SH AUTHOR
  1722. XRich $alz <rsalz@bbn.com>, after a set of scripts and a excellent manpage by
  1723. X.br
  1724. XErik E. Fair <fair@apple.com>.
  1725. X.br
  1726. XPiete Brooks <pb@computer-lab.cambridge.ac.uk> helped write the option-handling.
  1727. END_OF_FILE
  1728.   if test 5362 -ne `wc -c <'news2mail.1'`; then
  1729.     echo shar: \"'news2mail.1'\" unpacked with wrong size!
  1730.   fi
  1731.   # end of 'news2mail.1'
  1732. fi
  1733. if test -f 'signoff.c' -a "${1}" != "-c" ; then 
  1734.   echo shar: Will not clobber existing file \"'signoff.c'\"
  1735. else
  1736.   echo shar: Extracting \"'signoff.c'\" \(3327 characters\)
  1737.   sed "s/^X//" >'signoff.c' <<'END_OF_FILE'
  1738. X/*
  1739. X**  SIGNOFF
  1740. X**  Quickie hack to see of a mail message is a "please drop me" request.
  1741. X**  Exit's with status 0 if it is a regular message, or 1 if it appears to
  1742. X**  be a one of this administrative requests that annoy everyone when
  1743. X**  they're sent to the whole list.  Optional first argument is the name
  1744. X**  of the input file, or stdin is read if none is given.
  1745. X**
  1746. X**  Original program written by Russ Nelson, <nelson@clutx.clarkson.edu>.
  1747. X**  Severely hacked on by Rich $alz, <rsalz@bbn.com>.  This program is
  1748. X**  basically incorporated into mail2news; it's pulled out here for
  1749. X**  demonstration.
  1750. X**
  1751. X**  For example, here is a script that could be used as a wrapper around
  1752. X**  the mail2news program:
  1753. X**    #! /bin/sh
  1754. X**    cat >/tmp/signoff$$
  1755. X**    if /usr/lib/news/signoff </tmp/signoff$$ ; then
  1756. X**        /usr/ucb/Mail -s "Sign on/off request" usenet </tmp/signoff$$
  1757. X**    else
  1758. X**        /usr/lib/news/mail2news.real </tmp/signoff$$
  1759. X**    fi
  1760. X**    exec rm /tmp/signoff$$
  1761. X**
  1762. X**  Russ ran the following test for a month and got only one real message
  1763. X**  (a gnu.gcc bug report) treated as a subscription request.  He doesn't
  1764. X**  know how many subs made it out to the net, tho:  that would entail
  1765. X**  reading ALL netnews articles -- yuck!
  1766. X**
  1767. X**  Put the following line in your news sys file:
  1768. X**    allmail:all::/usr/lib/news/ts
  1769. X**  here is the "ts" script:
  1770. X**    #! /bin/sh
  1771. X**    cat >/tmp/ts.$$
  1772. X**    /usr/lib/news/signoff </tmp/ts.$$ || mail usenet </tmp/ts.$$
  1773. X**    exec rm /tmp/ts.$$
  1774. X**
  1775. X**  Perhaps a better way to test is to make the test less conservative,
  1776. X**  and see what "real" articles get caught, and make adjustments then?
  1777. X**  Comments solicited.
  1778. X*/
  1779. X#include <stdio.h>
  1780. X#include <ctype.h>
  1781. X
  1782. X#define EQ(a, b)        (strcmp((a), (b)) == 0)
  1783. X
  1784. X
  1785. Xmain(ac, av)
  1786. X    int            ac;
  1787. X    char        *av[];
  1788. X{
  1789. X    register FILE    *F;
  1790. X    register char    *p;
  1791. X    register int    c;
  1792. X    register int    drop_or_add;
  1793. X    register int    from_or_to;
  1794. X    register int    mail_word;
  1795. X    register int    count;
  1796. X    char        word[128];
  1797. X
  1798. X    /* Get input. */
  1799. X    if (ac < 2)
  1800. X    F = stdin;
  1801. X    else if ((F = fopen(av[1], "r")) == NULL) {
  1802. X    (void)fprintf(stderr, "%s: cannot open %s\n", av[0], av[1]);
  1803. X    exit(1);
  1804. X    }
  1805. X
  1806. X    /* Skip headers by waiting for the first blank line. */
  1807. X    while (fgets(word, sizeof word, F) && *word != '\n')
  1808. X        ;
  1809. X
  1810. X    /* Clear counts. */
  1811. X    drop_or_add = 0;
  1812. X    from_or_to = 0;
  1813. X    mail_word = 0;
  1814. X    count = 0;
  1815. X
  1816. X    /* Read input a word at a time. */
  1817. X    for (p = word; (c = getc(F)) != EOF; ) {
  1818. X    if (!isalpha(c)) {
  1819. X        *p = '\0';
  1820. X        if (p > word)
  1821. X        count++;
  1822. X        p = word;
  1823. X
  1824. X        if (EQ(word, "remove") || EQ(word, "drop") || EQ(word, "off")
  1825. X         || EQ(word, "subscribe") || EQ(word, "get") || EQ(word, "add"))
  1826. X        drop_or_add++;
  1827. X        else if (EQ(word, "from") || EQ(word, "to"))
  1828. X        from_or_to++;
  1829. X        else if (EQ(word, "mail") || EQ(word, "mailing")
  1830. X          || EQ(word, "list") || EQ(word, "dl"))
  1831. X        mail_word++;
  1832. X    }
  1833. X    else if (p < &word[sizeof word - 1])
  1834. X        *p++ = isupper(c) ? tolower(c) : c;
  1835. X    }
  1836. X
  1837. X    (void)fclose(F);
  1838. X
  1839. X    /* Use fancy-shmancy AI techniques to determine what the message is. */
  1840. X    c = count < 25 && drop_or_add && from_or_to && mail_word;
  1841. X
  1842. X#ifdef    DEBUG
  1843. X    printf("%s: %d words, %d drop, %d mail --> %s\n",
  1844. X       av[1] ? av[1] : "<stdin>",
  1845. X       count, drop_or_add, mail_word,
  1846. X       c ? "yes" : "no");
  1847. X#endif    /* DEBUG */
  1848. X
  1849. X    /* Exit appropriately. */
  1850. X    exit(c ? 0 : 1);
  1851. X}
  1852. END_OF_FILE
  1853.   if test 3327 -ne `wc -c <'signoff.c'`; then
  1854.     echo shar: \"'signoff.c'\" unpacked with wrong size!
  1855.   fi
  1856.   # end of 'signoff.c'
  1857. fi
  1858. if test -f 'sysexits.h' -a "${1}" != "-c" ; then 
  1859.   echo shar: Will not clobber existing file \"'sysexits.h'\"
  1860. else
  1861.   echo shar: Extracting \"'sysexits.h'\" \(4568 characters\)
  1862.   sed "s/^X//" >'sysexits.h' <<'END_OF_FILE'
  1863. X/*
  1864. X * Copyright (c) 1987 Regents of the University of California.
  1865. X * All rights reserved.
  1866. X *
  1867. X * Redistribution and use in source and binary forms are permitted
  1868. X * provided that the above copyright notice and this paragraph are
  1869. X * duplicated in all such forms and that any documentation,
  1870. X * advertising materials, and other materials related to such
  1871. X * distribution and use acknowledge that the software was developed
  1872. X * by the University of California, Berkeley.  The name of the
  1873. X * University may not be used to endorse or promote products derived
  1874. X * from this software without specific prior written permission.
  1875. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1876. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1877. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1878. X *
  1879. X *    @(#)sysexits.h    4.5 (Berkeley) 7/6/88
  1880. X */
  1881. X
  1882. X/*
  1883. X**  SYSEXITS.H -- Exit status codes for system programs.
  1884. X**
  1885. X**    This include file attempts to categorize possible error
  1886. X**    exit statuses for system programs, notably delivermail
  1887. X**    and the Berkeley network.
  1888. X**
  1889. X**    Error numbers begin at EX__BASE to reduce the possibility of
  1890. X**    clashing with other exit statuses that random programs may
  1891. X**    already return.  The meaning of the codes is approximately
  1892. X**    as follows:
  1893. X**
  1894. X**    EX_USAGE -- The command was used incorrectly, e.g., with
  1895. X**        the wrong number of arguments, a bad flag, a bad
  1896. X**        syntax in a parameter, or whatever.
  1897. X**    EX_DATAERR -- The input data was incorrect in some way.
  1898. X**        This should only be used for user's data & not
  1899. X**        system files.
  1900. X**    EX_NOINPUT -- An input file (not a system file) did not
  1901. X**        exist or was not readable.  This could also include
  1902. X**        errors like "No message" to a mailer (if it cared
  1903. X**        to catch it).
  1904. X**    EX_NOUSER -- The user specified did not exist.  This might
  1905. X**        be used for mail addresses or remote logins.
  1906. X**    EX_NOHOST -- The host specified did not exist.  This is used
  1907. X**        in mail addresses or network requests.
  1908. X**    EX_UNAVAILABLE -- A service is unavailable.  This can occur
  1909. X**        if a support program or file does not exist.  This
  1910. X**        can also be used as a catchall message when something
  1911. X**        you wanted to do doesn't work, but you don't know
  1912. X**        why.
  1913. X**    EX_SOFTWARE -- An internal software error has been detected.
  1914. X**        This should be limited to non-operating system related
  1915. X**        errors as possible.
  1916. X**    EX_OSERR -- An operating system error has been detected.
  1917. X**        This is intended to be used for such things as "cannot
  1918. X**        fork", "cannot create pipe", or the like.  It includes
  1919. X**        things like getuid returning a user that does not
  1920. X**        exist in the passwd file.
  1921. X**    EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
  1922. X**        etc.) does not exist, cannot be opened, or has some
  1923. X**        sort of error (e.g., syntax error).
  1924. X**    EX_CANTCREAT -- A (user specified) output file cannot be
  1925. X**        created.
  1926. X**    EX_IOERR -- An error occurred while doing I/O on some file.
  1927. X**    EX_TEMPFAIL -- temporary failure, indicating something that
  1928. X**        is not really an error.  In sendmail, this means
  1929. X**        that a mailer (e.g.) could not create a connection,
  1930. X**        and the request should be reattempted later.
  1931. X**    EX_PROTOCOL -- the remote system returned something that
  1932. X**        was "not possible" during a protocol exchange.
  1933. X**    EX_NOPERM -- You did not have sufficient permission to
  1934. X**        perform the operation.  This is not intended for
  1935. X**        file system problems, which should use NOINPUT or
  1936. X**        CANTCREAT, but rather for higher level permissions.
  1937. X**        For example, kre uses this to restrict who students
  1938. X**        can send mail to.
  1939. X**
  1940. X**    Maintained by Eric Allman (eric@berkeley, ucbvax!eric) --
  1941. X**        please mail changes to me.
  1942. X**
  1943. X**            @(#)sysexits.h    4.5        7/6/88
  1944. X*/
  1945. X
  1946. X# define EX_OK        0    /* successful termination */
  1947. X
  1948. X# define EX__BASE    64    /* base value for error messages */
  1949. X
  1950. X# define EX_USAGE    64    /* command line usage error */
  1951. X# define EX_DATAERR    65    /* data format error */
  1952. X# define EX_NOINPUT    66    /* cannot open input */
  1953. X# define EX_NOUSER    67    /* addressee unknown */
  1954. X# define EX_NOHOST    68    /* host name unknown */
  1955. X# define EX_UNAVAILABLE    69    /* service unavailable */
  1956. X# define EX_SOFTWARE    70    /* internal software error */
  1957. X# define EX_OSERR    71    /* system error (e.g., can't fork) */
  1958. X# define EX_OSFILE    72    /* critical OS file missing */
  1959. X# define EX_CANTCREAT    73    /* can't create (user) output file */
  1960. X# define EX_IOERR    74    /* input/output error */
  1961. X# define EX_TEMPFAIL    75    /* temp failure; user is invited to retry */
  1962. X# define EX_PROTOCOL    76    /* remote error in protocol */
  1963. X# define EX_NOPERM    77    /* permission denied */
  1964. X# define EX_CONFIG    78    /* configuration error */
  1965. END_OF_FILE
  1966.   if test 4568 -ne `wc -c <'sysexits.h'`; then
  1967.     echo shar: \"'sysexits.h'\" unpacked with wrong size!
  1968.   fi
  1969.   # end of 'sysexits.h'
  1970. fi
  1971. if test -f 'uucp-2-inet' -a "${1}" != "-c" ; then 
  1972.   echo shar: Will not clobber existing file \"'uucp-2-inet'\"
  1973. else
  1974.   echo shar: Extracting \"'uucp-2-inet'\" \(3301 characters\)
  1975.   sed "s/^X//" >'uucp-2-inet' <<'END_OF_FILE'
  1976. X##  This file maps UUCP names to Internet names.
  1977. X##  Blank lines, and lines starting with # are ignored.
  1978. X##  $Header: /nfs/papaya/u2/rsalz/src/newsgate/src/RCS/uucp-2-inet,v 1.2 87/10/01 14:06:50 rsalz Release1 $
  1979. X##  (I added uunet and bbn.)
  1980. Xames            ames.arpa
  1981. Xaurora            ames-aurora.arpa
  1982. Xkestrel            kestrel.arpa
  1983. Xlll-crg            lll-crg.arpa
  1984. Xlll-lcc            lll-lcc.arpa
  1985. Xstyx            lll-tis-b.arpa
  1986. Xcmcl2            nyu.arpa
  1987. Xyale            yale.arpa
  1988. Xrandvax            rand-unix.arpa
  1989. Xosu-eddie        ohio-state.arpa
  1990. Xuunet            uunet.uu.net
  1991. X
  1992. Xcunyvm.bitnet        cunyvm.bitnet
  1993. Xpsuvm.bitnet        psuvm.bitnet
  1994. X
  1995. Xmcnc            mcnc.org
  1996. X
  1997. Xbrl-smoke        smoke.brl.mil
  1998. Xbrl-sem            sem.brl.mil
  1999. Xbrl-adm            adm.brl.mil
  2000. Xcod            cod.nosc.mil
  2001. Xmarlin            marlin.nosc.mil
  2002. Xmplvax            mplvax.nosc.mil
  2003. Xnoscvax            bass.nosc.mil
  2004. X
  2005. Xelroy            elroy.jpl.nasa.gov
  2006. Xseismo            seismo.css.gov
  2007. Xlanl            lanl.gov
  2008. Xmordor            mordor.s1.gov
  2009. Xhc            hc.dspo.gov
  2010. X
  2011. Xbbn            bbn.com
  2012. Xhplabs            hplabs.hp.com
  2013. Xdecwrl            decwrl.dec.com
  2014. Xbellcore        bellcore.bellcore.com
  2015. Xpetrus            petrus.bellcore.com
  2016. XDiamond            diamond.bbn.com
  2017. Xsun            sun.com
  2018. Xsri-spam        spam.istc.sri.com
  2019. Xsri-unix        unix.sri.com
  2020. Xthink            think.com
  2021. Xburdvax            burdvax.prc.unisys.com
  2022. Xbigburd            bigburd.prc.unisys.com
  2023. Xparcvax            parcvax.xerox.com
  2024. X
  2025. Xarizona            arizona.edu
  2026. XShasta            shasta.stanford.edu
  2027. Xacf2            acf2.nyu.edu
  2028. Xacf3            acf3.nyu.edu
  2029. Xacf4            acf4.nyu.edu
  2030. Xcsd2            csd2.nyu.edu
  2031. Xmit-athena        athena.mit.edu
  2032. Xathena.mit.edu        athena.mit.edu
  2033. Xbatcomputer        tcgould.tn.cornell.edu
  2034. Xbu-cs            bu-cs.bu.edu
  2035. Xbucsb.bu.edu        bucsb.bu.edu
  2036. Xcaip            caip.rutgers.edu
  2037. Xcit-vax            csvax.caltech.edu
  2038. Xcit-vlsi        vlsi.caltech.edu
  2039. Xcornell            cu-arpa.cs.cornell.edu
  2040. Xcvl            cvl.umd.edu
  2041. Xendor            endor.harvard.edu
  2042. Xeneevax            eneevax.umd.edu
  2043. Xernie.Berkeley.EDU    ernie.berkeley.edu
  2044. Xglacier            glacier.stanford.edu
  2045. Xgvax            gvax.cs.cornell.edu
  2046. Xgymble            gymble.umd.edu
  2047. Xh.cc.purdue.edu        h.cc.purdue.edu
  2048. Xprinceton        princeton.edu
  2049. Xharvard            harvard.harvard.edu
  2050. Xhusc4            husc4.harvard.edu
  2051. Xhusc6            husc6.harvard.edu
  2052. Xoddjob            oddjob.uchicago.edu
  2053. Xgargoyle        gargoyle.uchicago.edu
  2054. Xsphinx            sphinx.uchicago.edu
  2055. Xim4u            im4u.utexas.edu
  2056. Xius2.cs.cmu.edu        ius2.cs.cmu.edu
  2057. Xsei.cmu.edu        sei.cmu.edu
  2058. Xj.cc.purdue.edu        j.cc.purdue.edu
  2059. Xll-xn            xn.ll.mit.edu
  2060. Xmimsy            mimsy.umd.edu
  2061. Xmit-amt            media-lab.media.mit.edu
  2062. Xmit-athena        athena.mit.edu
  2063. Xmit-eddie        eddie.mit.edu
  2064. Xmit-hermes        hermes.ai.mit.edu
  2065. Xmit-prep        prep.ai.mit.edu
  2066. Xmit-trillian        trillian.mit.edu
  2067. Xprep.ai.mit.edu        prep.ai.mit.edu
  2068. Xpt.cs.cmu.edu        pt.cs.cmu.edu
  2069. Xpur-ee            ee.ecn.purdue.edu
  2070. Xpurdue            purdue.edu
  2071. Xriacs            icarus.riacs.edu
  2072. Xrice            rice.edu
  2073. Xrochester        cs.rochester.edu
  2074. Xrover.ri.cmu.edu    rover.ri.cmu.edu
  2075. Xrutgers            rutgers.rutgers.edu
  2076. Xsdcsvax            sdcsvax.ucsd.edu
  2077. Xspice.cs.cmu.edu    spice.cs.cmu.edu
  2078. Xsvax            svax.cs.cornell.edu
  2079. Xtalcott            talcott.harvard.edu
  2080. Xtopaz            topaz.rutgers.edu
  2081. Xucbcad            cad.berkeley.edu
  2082. Xucbvax            ucbvax.berkeley.edu
  2083. Xucla-cs            locus.ucla.edu
  2084. Xuiucdcs            a.cs.uiuc.edu
  2085. Xuiucdcsb        b.cs.uiuc.edu
  2086. Xuiucdcsc        c.cs.uiuc.edu
  2087. Xuiucdcsm        m.cs.uiuc.edu
  2088. Xuiucdcsp        p.cs.uiuc.edu
  2089. Xuiucuxc            uxc.cso.uiuc.edu
  2090. Xumcp-cs            mimsy.umd.edu
  2091. Xumd5            umd5.umd.edu
  2092. Xoberon            usc-oberon.usc.edu
  2093. Xut-ngp            ngp.utexas.edu
  2094. Xut-sally        sally.utexas.edu
  2095. Xutah-cs            cs.utah.edu
  2096. Xutah-gr            gr.utah.edu
  2097. Xutastro            astro.as.utexas.edu
  2098. Xuw-beaver        beaver.cs.washington.edu
  2099. Xuw-june            june.cs.washington.edu
  2100. Xuwmacc            unix.macc.wisc.edu
  2101. Xuwvax            rsch.wisc.edu
  2102. Xwjh12            wjh12.harvard.edu
  2103. X
  2104. XCS.UCL.AC.UK        cs.ucl.ac.uk
  2105. Xcs.ucl.ac.uk        cs.ucl.ac.uk
  2106. END_OF_FILE
  2107.   if test 3301 -ne `wc -c <'uucp-2-inet'`; then
  2108.     echo shar: \"'uucp-2-inet'\" unpacked with wrong size!
  2109.   fi
  2110.   # end of 'uucp-2-inet'
  2111. fi
  2112. echo shar: End of archive 3 \(of 4\).
  2113. cp /dev/null ark3isdone
  2114. MISSING=""
  2115. for I in 1 2 3 4 ; do
  2116.     if test ! -f ark${I}isdone ; then
  2117.     MISSING="${MISSING} ${I}"
  2118.     fi
  2119. done
  2120. if test "${MISSING}" = "" ; then
  2121.     echo You have unpacked all 4 archives.
  2122.     rm -f ark[1-9]isdone
  2123. else
  2124.     echo You still must unpack the following archives:
  2125.     echo "        " ${MISSING}
  2126. fi
  2127. exit 0
  2128. exit 0 # Just in case...
  2129.